﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Collections.ObjectModel;
using System.Drawing;

using System.Collections;
using Incendios0_1.tools;
using Incendios0_1.Camera.media.filters;
using Emgu.CV;
using Emgu.CV.Structure;
using System.Windows;
using System.Windows.Controls;
using Emgu.CV.UI;
using System.Data.Linq;
using Incendios0_1.Camera.localization;


namespace Incendios0_1.Camera.wpfdatamanager
{
    class CameraManager
    {
        public static ObservableCollection<CameraData> CamerasData { get; set; }
        public static Dictionary<CameraData, AbstractCamera> cameras;
        public static List<CameraSink> displays;
        public static Firedata db { get; set; }
        public static localizacion windowMap;
        public static Object lk = new Object();

        public static localizacion WindowMap
        {
            get
            {
                lock (lk)
                {
                    if (windowMap == null)
                    {
                        windowMap = new localizacion();
                    }
                    return windowMap;
                }
            }
        }

        public static void InitializeCameras()
        {
            DebugTextWriter writer = new DebugTextWriter();
            displays = new List<CameraSink>();
            db = DBControler.db;
            CamerasData = new ObservableCollection<CameraData>(from c in db.CameraData
                                                            select c);
            cameras = new Dictionary<CameraData, AbstractCamera>();
            foreach (CameraData c in CamerasData)
            {
                AbstractCamera nCamera = CameraFactory.CreateCamera(c);
                if (nCamera != null)
                {
                    cameras.Add(c, nCamera);
                }
            }
        }

        public static CameraData SearchCamera(int CameraNum)
        {
            IQueryable<CameraData> users = from u
                                       in DBControler.db.CameraData
                                      where u.HWControlAddress == CameraNum
                                      select u;
            if (users.Count() > 0)
                return users.First();
            else
                return null;
        }

        public static CameraData SaveChanges()
        {
            if (DBControler.SaveChanges() == null)
            {
                CamerasData = new ObservableCollection<CameraData>(from c in DBControler.db.CameraData
                                                                       select c);
                return CamerasData[CamerasData.Count - 1];
            }
            return null;
        }

        internal static void Cancel(CameraData camera)
        {
            DBControler.db.Refresh(RefreshMode.OverwriteCurrentValues, camera);
        }


        public static void AddCamera(CameraData newCamera)
        {
            db.CameraData.InsertOnSubmit(newCamera);
        }

        public static void SaveCamera()
        {
            DBControler.SaveChanges();
        }

        public static void deleteCamera(CameraData camera)
        {
            db.CameraData.DeleteOnSubmit(camera);
            db.SubmitChanges();
            CamerasData = new ObservableCollection<CameraData>(from c in db.CameraData
                                                            select c);
        }

        public static void Close()
        {
            if (db!=null)
                db.Connection.Close();
        }

        public static bool isEmpty()
        {
            if (CamerasData.Count <= 0)
                return true;
            else
                return false;
        }

        public static void InitializeDisplays(int numCameras)
        {
            for (int x = 0; x < numCameras; x++)
            {
                CameraSink dcc = new CameraSink();
                displays.Add(dcc);
                if (x < cameras.Count)
                {
                    cameras[CamerasData[x]].PlugIn(dcc.sink);
                    dcc.sink.Display.Link = cameras[CamerasData[x]];
                    System.Windows.Forms.ContextMenu mnu = ContextMenuFactory.createContextMenu();
                    mnu.MenuItems.AddRange(ContextMenuFactory.createMenuItems(cameras[CamerasData[x]]));
                    dcc.Display.ContextMenu = mnu;
                }
                else
                {
                    System.Windows.Forms.ContextMenu mnu = ContextMenuFactory.createContextMenu();
                    mnu.MenuItems.AddRange(ContextMenuFactory.createMenuItems(null));
                    dcc.Display.ContextMenu = mnu;
                }
            }
        }

        public static void StartCapture()
        {
            for (int i = 0; i < CamerasData.Count; i++)
            {
                cameras[CamerasData[i]].Start();
            }
        }

        public static void StartCapture(LoadState state, int maxVal)
        {
            state.CurrentOperation = "Inicializando Camaras";
            for (int i = 0; i < CamerasData.Count; i++)
            {
                state.OperationMessage = String.Format("Inicialicando camara {0}/{1}", i+1, CamerasData.Count);
                cameras[CamerasData[i]].Start();
                state.Proggresion += maxVal / CamerasData.Count;
            }
        }

        public static void StopCapture()
        {
            if (CamerasData != null && cameras != null)
            {
                for (int i = 0; i < CamerasData.Count; i++)
                {
                    if (cameras[CamerasData[i]] != null)
                        cameras[CamerasData[i]].Stop();
                }
                Close();
            }
        }
    }
}
